package com.xinlan.imageeditlibrary;

import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.baselibrary.utils.DoubleUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.bumptech.glide.signature.ObjectKey;
import com.xinlan.imageeditlibrary.editimage.fragment.AddTextFragment;
import com.xinlan.imageeditlibrary.editimage.fragment.CropFragment;
import com.xinlan.imageeditlibrary.editimage.fragment.FilterListFragment;
import com.xinlan.imageeditlibrary.editimage.fragment.PaintFragment;
import com.xinlan.imageeditlibrary.editimage.fragment.RotateFragment;
import com.xinlan.imageeditlibrary.editimage.fragment.StickerFragment;
import com.xinlan.imageeditlibrary.editimage.model.OnBackPressedCallBack;
import com.xinlan.imageeditlibrary.editimage.model.OnNextStepClickListener;
import com.xinlan.imageeditlibrary.editimage.utils.BaseUtils;
import com.xinlan.imageeditlibrary.editimage.utils.BitmapUtils;
import com.xinlan.imageeditlibrary.editimage.utils.DiaLogUtils;
import com.xinlan.imageeditlibrary.editimage.view.CropImageView;
import com.xinlan.imageeditlibrary.editimage.view.CustomPaintView;
import com.xinlan.imageeditlibrary.editimage.view.RotateImageView;
import com.xinlan.imageeditlibrary.editimage.view.StickerView;
import com.xinlan.imageeditlibrary.editimage.view.TextStickerView;
import com.xinlan.imageeditlibrary.editimage.view.imagezoom.ImageViewTouch;
import com.xinlan.imageeditlibrary.editimage.view.imagezoom.ImageViewTouchBase;
import com.xinlan.imageeditlibrary.editimage.widget.RedoUndoController;

/**
 * <p>
 * 图片编辑 主页面
 *
 * @author panyi
 * <p>
 * 包含 1.贴图 2.滤镜 3.剪裁 4.底图旋转 功能
 * add new modules
 */
public class EditImageFragment extends BaseEditFragment implements OnClickListener {
    public static final String FILE_PATH = "file_path";
    public static final String EXTRA_OUTPUT = "extra_output";
    public static final String SAVE_FILE_PATH = "save_file_path";

    public static final String IMAGE_IS_EDIT = "image_is_edit";

    public static final int MODE_NONE = 0;
    public static final int MODE_STICKERS = 1;// 贴图模式
    public static final int MODE_FILTER = 2;// 滤镜模式
    public static final int MODE_CROP = 3;// 剪裁模式
    public static final int MODE_ROTATE = 4;// 旋转模式
    public static final int MODE_TEXT = 5;// 文字模式
    public static final int MODE_PAINT = 6;//绘制模式
    public static final int MODE_BEAUTY = 7;//美颜模式

    public String filePath;// 需要编辑图片路径
    public String saveFilePath;// 生成的新图片路径
    private int imageWidth, imageHeight;// 展示图片控件 宽 高
    private LoadImageTask mLoadImageTask;
    public int mode = MODE_NONE;// 当前操作模式
    protected int mOpTimes = 0;
    protected boolean isBeenSaved = false;
    private Bitmap mainBitmap;// 底层显示Bitmap
    public ImageViewTouch mainImage;
    public StickerView mStickerView;// 贴图层View
    public CropImageView mCropPanel;// 剪切操作控件
    public RotateImageView mRotatePanel;// 旋转操作控件
    public TextStickerView mTextStickerView;//文本贴图显示View
    public CustomPaintView mPaintView;//涂鸦模式画板

    public StickerFragment mStickerFragment;// 贴图Fragment
    public FilterListFragment mFilterListFragment;// 滤镜FliterListFragment
    public CropFragment mCropFragment;// 图片剪裁Fragment
    public RotateFragment mRotateFragment;// 图片旋转Fragment
    public AddTextFragment mAddTextFragment;//图片添加文字
    public PaintFragment mPaintFragment;//绘制模式Fragment
    public BaseEditFragment mLasFragment;//纪录上次操作

    private RedoUndoController mRedoUndoController;//撤销操作
    private View mEditImgView;
    public LinearLayout mTvTiaoZheng, mTvLvJing, mTvMeiYan, mTvTieZhi, mTvWenZi, mTvQueDing, mTvTuYa;
    private FragmentManager mFragmentManager;
    public OnBackPressedCallBack mOnBackPressedCallBack;
    private EditImgMainActivity mActivity;
    public LinearLayout mLlBottom;
    public OnNextStepClickListener listener;
    //    private ImageView mIvEditBack;
    private int CROPMARGIN = 50;
    int saveStickerAndAddTextCount = 0;
    private static final String TAG = "EditImageFragment";
    //是否通过eventbus 传值
    private boolean isPassEventbus;

    public static EditImageFragment newInstance(boolean isPassEventbus, EditImgMainActivity activity, OnNextStepClickListener listener) {
        EditImageFragment fragment = new EditImageFragment();
        fragment.setActivity(activity);
        fragment.setIsPassEventBus(isPassEventbus);
        fragment.setListener(listener);
        fragment.setOnBackPressedCallBack();

        return fragment;
    }

    public void setIsPassEventBus(boolean isPassEventbus) {
        this.isPassEventbus = isPassEventbus;
    }

    public void setActivity(EditImgMainActivity activity) {
        this.mActivity = activity;
    }

    public void setListener(OnNextStepClickListener listener) {
        this.listener = listener;
    }

    public OnBackPressedCallBack getOnBackPressedCallBack() {
        return mOnBackPressedCallBack;
    }

    public void setOnBackPressedCallBack() {
        mOnBackPressedCallBack = new OnBackPressedCallBack() {
            @Override
            public void onBack() {
                switch (mode) {
                    case MODE_STICKERS:
                        mStickerFragment.backToMain();
                        return;
                    case MODE_FILTER:// 滤镜编辑状态
                        mFilterListFragment.backToMain();// 保存滤镜贴图
                        return;
                    case MODE_CROP:// 剪切图片保存
                        View inflate = getLayoutInflater().inflate(R.layout.dialog_crop, null);
                        final AlertDialog alertDialog = DiaLogUtils.showDialog(mActivity, inflate);
                        inflate.findViewById(R.id.tv_dialog_confirm).setOnClickListener(new OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                if (alertDialog.isShowing())
                                    alertDialog.dismiss();
                                mCropFragment.initOriginal();
                                mCropFragment.backToMain();
                            }
                        });
                        inflate.findViewById(R.id.tv_dialog_cancel).setOnClickListener(new OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                if (alertDialog.isShowing())
                                    alertDialog.dismiss();
                            }
                        });

                        return;
                    case MODE_ROTATE:// 旋转图片保存
                        mRotateFragment.backToMain();
                        return;
                    case MODE_TEXT:
                        mAddTextFragment.backToMain();
                        return;
                    case MODE_PAINT:
                        mPaintFragment.backToMain();
                        return;
                }// end switch

                View inflate = getLayoutInflater().inflate(R.layout.dialog_crop, null);
                final AlertDialog alertDialog = DiaLogUtils.showDialog(mActivity, inflate);
                inflate.findViewById(R.id.tv_dialog_confirm).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (alertDialog.isShowing())
                            alertDialog.dismiss();
                        activity.finish();
                    }
                });
                inflate.findViewById(R.id.tv_dialog_cancel).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (alertDialog.isShowing())
                            alertDialog.dismiss();
                    }
                });
            }
        };
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        BaseUtils.checkInitImageLoader(getActivity());
        mEditImgView = inflater.inflate(R.layout.activity_image_edit_two, null);
        return mEditImgView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initView();
        initListener();
        getData();
    }

    private void initListener() {
        mTvTiaoZheng.setOnClickListener(this);
        mTvLvJing.setOnClickListener(this);
        mTvMeiYan.setOnClickListener(this);
        mTvWenZi.setOnClickListener(this);
        mTvTieZhi.setOnClickListener(this);
        mTvQueDing.setOnClickListener(this);
        mTvTuYa.setOnClickListener(this);
        //mIvEditBack.setOnClickListener(this);
    }

    private void getData() {
        assert getArguments() != null;
        filePath = getArguments().getString(FILE_PATH);
        saveFilePath = getArguments().getString(EXTRA_OUTPUT);// 保存图片路径
        loadImage(filePath);
    }

    private void initView() {

        mTvTiaoZheng = mEditImgView.findViewById(R.id.tv_editimg_tiaozheng);
        mTvLvJing = mEditImgView.findViewById(R.id.tv_editimg_lvjing);
        mTvMeiYan = mEditImgView.findViewById(R.id.tv_editimg_meiyan);
        mTvTieZhi = mEditImgView.findViewById(R.id.tv_editimg_tiezhi);
        mTvWenZi = mEditImgView.findViewById(R.id.tv_editimg_wenzi);
        mTvQueDing = mEditImgView.findViewById(R.id.tv_editimg_queding);
        mTvTuYa = mEditImgView.findViewById(R.id.tv_editimg_tuya);
        mainImage = mEditImgView.findViewById(R.id.main_image);
        mStickerView = mEditImgView.findViewById(R.id.sticker_panel);
        mCropPanel = mEditImgView.findViewById(R.id.crop_panel);
        mRotatePanel = mEditImgView.findViewById(R.id.rotate_panel);
        mTextStickerView = mEditImgView.findViewById(R.id.text_sticker_panel);
        mPaintView = mEditImgView.findViewById(R.id.custom_paint_view);
        mLlBottom = mEditImgView.findViewById(R.id.ll_bottom);
//        mIvEditBack = mEditImgView.findViewById(R.id.iv_edit_back);

        DisplayMetrics metrics = getResources().getDisplayMetrics();
        imageWidth = metrics.widthPixels / 2;
        imageHeight = metrics.heightPixels / 2;

        swFragment(-1);

        mainImage.isCorp(true);
        mainImage.setFlingListener(new ImageViewTouch.OnImageFlingListener() {
            @Override
            public void onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if (velocityY > 1) {
                    closeInputMethod();
                }
            }
        });

        mRedoUndoController = new RedoUndoController(this, mEditImgView);


        mainImage.setOnDrawableChangedListener(new ImageViewTouchBase.OnDrawableChangeListener() {
            @Override
            public void onDrawableChanged(Drawable drawable) {
                Log.d(TAG, "onDrawableChanged: ");
            }
        });
        mainImage.setOnLayoutChangeListener(new ImageViewTouchBase.OnLayoutChangeListener() {
            @Override
            public void onLayoutChanged(boolean changed, int left, int top, int right, int bottom) {
                Log.d(TAG, "onLayoutChanged: ");
            }
        });
        if (isPassEventbus) {
            //需要隐藏 滤镜、涂鸦、加文字、贴纸
            mTvLvJing.setVisibility(View.INVISIBLE);
            mTvTieZhi.setVisibility(View.INVISIBLE);
            mTvWenZi.setVisibility(View.INVISIBLE);
            mTvTuYa.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 关闭输入法
     */
    private void closeInputMethod() {
        if (mAddTextFragment.isAdded()) {
            mAddTextFragment.hideInput();
        }
    }

    @Override
    public void onShow() {

    }

    @Override
    public void backToMain() {

    }

    @Override
    public void onClick(View view) {

        int id = view.getId();
        if (id == R.id.tv_editimg_tiaozheng) {
            //mainImage.isCorp(true);
            swFragment(1);
        } else if (id == R.id.tv_editimg_lvjing) {
            //mainImage.isCorp(false);
            swFragment(2);
        } else if (id == R.id.tv_editimg_tuya) {
            //mainImage.isCorp(false);
            swFragment(3);
        } else if (id == R.id.tv_editimg_tiezhi) {
            //mainImage.isCorp(false);
            swFragment(4);
        } else if (id == R.id.tv_editimg_wenzi) {
            //mainImage.isCorp(false);
            swFragment(5);
        } /*else if (id == R.id.iv_edit_back) {
            //mainImage.isCorp(false);
            if (mOnBackPressedCallBack != null)
                mOnBackPressedCallBack.onBack();
        }*/ else if (id == R.id.tv_editimg_queding) {
            if (DoubleUtils.isFastDoubleClick()) return;
            //mainImage.isCorp(false);
            mTvQueDing.setEnabled(false);
            for (EditImageFragment editImageFragment : mActivity.mListFragment) {
                //因为可以多张编辑，循环依次保存所有Fragment的元素
                BaseUtils.addStickerAndText(editImageFragment.mAddTextFragment, editImageFragment.mStickerFragment, new BaseUtils.OnAddStickerAndText() {
                    @Override
                    public void onAddStickerAndText(int count) {
                        if (listener != null) {
                            saveStickerAndAddTextCount++;
                            if (saveStickerAndAddTextCount == mActivity.mListFragment.size()) {
                                saveStickerAndAddTextCount = 0;
                                listener.onNextStepClick();
                            }
                        }
                    }
                });
            }
        }
    }

    public void swFragment(int index) {
        if (mFragmentManager == null)
            mFragmentManager = getChildFragmentManager();
        if (mStickerFragment == null)
            mStickerFragment = StickerFragment.newInstance(this);
        if (mFilterListFragment == null)
            mFilterListFragment = FilterListFragment.newInstance(this);
        if (mCropFragment == null)
            mCropFragment = CropFragment.newInstance(this);
        if (mRotateFragment == null)
            mRotateFragment = RotateFragment.newInstance(this);
        if (mAddTextFragment == null)
            mAddTextFragment = AddTextFragment.newInstance(this);
        if (mPaintFragment == null)
            mPaintFragment = PaintFragment.newInstance(this);

        FragmentTransaction fragmentTransaction;
        switch (index) {
            case -1:
                fragmentTransaction = mFragmentManager.beginTransaction();
                if (!mCropFragment.isAdded() && mCropFragment.getTag() == null)
                    fragmentTransaction.add(R.id.work_space, mCropFragment, mCropFragment.getClass().getSimpleName());
                if (!mFilterListFragment.isAdded() && mFilterListFragment.getTag() == null)
                    fragmentTransaction.add(R.id.work_space, mFilterListFragment, mFilterListFragment.getClass().getSimpleName());
                if (!mStickerFragment.isAdded() && mStickerFragment.getTag() == null)
                    fragmentTransaction.add(R.id.work_space, mStickerFragment, mStickerFragment.getClass().getSimpleName());
                if (!mAddTextFragment.isAdded() && mAddTextFragment.getTag() == null)
                    fragmentTransaction.add(R.id.work_space, mAddTextFragment, mAddTextFragment.getClass().getSimpleName());
                if (!mPaintFragment.isAdded() && mPaintFragment.getTag() == null)
                    fragmentTransaction.add(R.id.work_space, mPaintFragment, mPaintFragment.getClass().getSimpleName());
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                break;
            case 0:
                mLlBottom.setVisibility(View.VISIBLE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = null;
                break;
            case 1:
                mLlBottom.setVisibility(View.GONE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.show(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                mCropFragment.onShow();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = mCropFragment;
                break;
            case 2:
                mLlBottom.setVisibility(View.VISIBLE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.show(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                mFilterListFragment.onShow();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = mFilterListFragment;
                break;
            case 3:
                mLlBottom.setVisibility(View.VISIBLE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.show(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                mPaintFragment.onShow();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = mPaintFragment;
                break;
            case 4:
                mLlBottom.setVisibility(View.VISIBLE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.show(mStickerFragment);
                fragmentTransaction.hide(mAddTextFragment);
                fragmentTransaction.commit();
                mStickerFragment.onShow();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = mStickerFragment;
                break;
            case 5:
                mLlBottom.setVisibility(View.VISIBLE);
                fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.hide(mCropFragment);
                fragmentTransaction.hide(mFilterListFragment);
                fragmentTransaction.hide(mPaintFragment);
                fragmentTransaction.hide(mStickerFragment);
                fragmentTransaction.show(mAddTextFragment);
                fragmentTransaction.commit();
                mAddTextFragment.onShow();
                BaseUtils.retainAction(mLasFragment);
                mLasFragment = mAddTextFragment;
                break;
        }

    }

    /**
     * 异步载入编辑图片
     *
     * @param filepath
     */
    public void loadImage(String filepath) {

        final RequestOptions userAvatarOptions = new RequestOptions()
                .signature(new ObjectKey(System.currentTimeMillis()));
        Glide.with(requireContext().getApplicationContext())
                .applyDefaultRequestOptions(userAvatarOptions)
                .asBitmap().load(filepath)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
                        changeMainBitmap(BitmapUtils.compress(bitmap), false);
                    }
                });
    }

    /**
     * 导入文件图片任务
     */
    private final class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(String... params) {
            return BitmapUtils.getSampledBitmap(params[0], imageWidth,
                    imageHeight);
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            int mBitHeight = result.getHeight();
            int mScreenHeight = BaseUtils.getScreenHeight(requireContext());
            if (mBitHeight >= mScreenHeight * 5) {
                mainImage.setLongGraph(true);
            }
            changeMainBitmap(result, false);
        }
    }

    /**
     * @param newBit
     * @param needPushUndoStack
     */
    public void changeMainBitmap(Bitmap newBit, boolean needPushUndoStack) {
        if (newBit == null)
            return;

        if (mainBitmap == null || mainBitmap != newBit) {
            if (needPushUndoStack) {
                mRedoUndoController.switchMainBit(mainBitmap, newBit);
                increaseOpTimes();
            }
            mainBitmap = newBit;
            mainImage.setImageBitmap(mainBitmap);
            if (!mainImage.getLongGraph()) {
                mainImage.setDisplayType(ImageViewTouchBase.DisplayType.FIT_TO_SCREEN);
            }

        }
    }

    public void setCropMargin(boolean isMargins) {
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mainImage.getLayoutParams();
        if (isMargins) {
            layoutParams.setMargins(CROPMARGIN, CROPMARGIN, CROPMARGIN, CROPMARGIN);
        } else {
            layoutParams.setMargins(0, 0, 0, 0);
        }
        mainImage.setLayoutParams(layoutParams);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
//        if (mLoadImageTask != null) {
//            mLoadImageTask.cancel(true);
//        }
//
//        if (mSaveImageTask != null) {
//            mSaveImageTask.cancel(true);
//        }
//
//        if (mRedoUndoController != null) {
//            mRedoUndoController.onDestroy();
//        }
//

    }

    @Override
    public void onStop() {
        super.onStop();
    }

    public void increaseOpTimes() {
        mOpTimes++;
        isBeenSaved = false;
    }

    public void resetOpTimes() {
        isBeenSaved = true;
    }

    public boolean canAutoExit() {
        return isBeenSaved || mOpTimes == 0;
    }

    /**
     * 返回上次界面
     */
    protected void onSaveTaskDone() {

    }

    public Bitmap getMainBit() {
        return mainBitmap;
    }
}// end class
